#ifndef BASE_PID_H
#define BASE_PID_H

/*********************
 *      INCLUDES
 *********************/
#include <stddef.h>
#include "stm32f4xx_hal.h"

/*********************
 *      DEFINES
 *********************/
#define USE_INCREMENTAL_MODE 1
#define USE_POSITIONAL_MODE  2
#define USE_WHELL_LEVEL      1
#define USE_CAR_LEVEL        2
#define my_abs(x) (((x)<0)?(-x):(x))
#define PID_DEBUG            1

/**********************
 *      TYPEDEFS
 **********************/
typedef struct {
    unsigned long now_time;
    unsigned long pre_time;
} timer_boj;

typedef struct {
    unsigned char conf;

    timer_boj timer;
    float aim;
    float real;

    float umax;
    float umin;

    float err_now;
    float err_last;
    float err_llast;

    float Kp, Ki, Kd;

#if PID_DEBUG
    float p, i, d;
#endif

    float integral;

    float *actuator;
} pid_obj;

/*********************
 *      FUNCTIONS
 *********************/
void pid_set_para(pid_obj *pid, float Kp, float Ki, float Kd);
void pid_get_para(pid_obj *pid, float *Kp, float *Ki, float *Kd);
void pid_set_limitation(pid_obj *pid, float umax, float umin);
void pid_clean_integral(pid_obj *pid);
void pid_bind_actuator(pid_obj *pid, float *actuator);
void pid_init(pid_obj *pid);
void pid_update(pid_obj *pid, float real, float aim, int enable_aim);
void pid_set_mode(pid_obj *pid, int mode);
void pid_set_kind(pid_obj *pid, int kind);
void pid_set_target(pid_obj *pid, float target);
unsigned long get_sys_time(timer_boj * pt);

#endif //BASE_PID_H
